﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using BarrierGenarator.Data;
using Snake;
using Snake.Data;
using Snake.GameBase;

namespace BarrierGenarator
{
    public partial class Frm_CreateMap : Form
    {

        public Frm_CreateMap()
        {
            InitializeComponent();
            saveFileDialog1.Filter = "Snake关卡文件(*.skb)|*.skb";
        }

        public Frm_CreateMap(string username)
        {
            InitializeComponent();
            saveFileDialog1.Filter = "Snake关卡文件(*.skb)|*.skb";
            Text = username;
        }

        List<LocationD> Walls = General.Walls;
        List<LocationD> Traps = General.Traps;
        JavaScriptSerializer js = new JavaScriptSerializer();

        private void Txt_sizex_TextChanged(object sender, EventArgs e)
        {

        }

        private void Addwall_Clicked(object sender, EventArgs e)
        {
            var wall = new LocationD(Convert.ToInt32(txt_wallx.Text), Convert.ToInt32(txt_wally.Text));
            Walls.Add(wall);
            txt_wallx.Text = "";
            txt_wally.Text = "";
            listBox1.Items.Add(wall);
        }

        private void Ck_dftcolor_CheckedChanged(object sender, EventArgs e)
        {
            if (ck_dftcolor.Checked)
            {
                pic_bg.Enabled = false;
                pic_body.Enabled = false;
                pic_food.Enabled = false;
                pic_head.Enabled = false;
                pic_wall.Enabled = false;
                pic_gate.Enabled = false;
                pic_trap.Enabled = false;
                pic_bg.BackColor = Color.Gray;
                pic_body.BackColor = Color.Blue;
                pic_food.BackColor = Color.Pink;
                pic_head.BackColor = Color.Red;
                pic_wall.BackColor = Color.Black;
                pic_gate.BackColor = Color.SkyBlue;
                pic_trap.BackColor = Color.Brown;
            }
            else
            {
                pic_bg.Enabled = true;
                pic_body.Enabled = true;
                pic_food.Enabled = true;
                pic_head.Enabled = true;
                pic_wall.Enabled = true;
                pic_gate.Enabled = true;
                pic_trap.Enabled = true;
            }
        }
        Barrier b;
        private void Btn_start_Click(object sender, EventArgs e)
        {
            try
            {
                SnakeD snake = new SnakeD();
                snake.Bodys = new List<LocationD>();
                snake.Head = new LocationD(Convert.ToInt32(txt_headx.Text), Convert.ToInt32(txt_heady.Text));
                for (int i = snake.Head.X - 1; i >= snake.Head.Y - Convert.ToInt32(txt_snakelen.Text); i--)
                {
                    snake.Bodys.Add(new LocationD(i, snake.Head.Y));
                }

                b = new Barrier
                {
                    FactoryOptions = new FactoryOptions
                    {
                        BackGround = ColorD.FromColor(pic_bg.BackColor),
                        Food = ColorD.FromColor(pic_food.BackColor),
                        SnakeBody = ColorD.FromColor(pic_body.BackColor),
                        SnakeHead = ColorD.FromColor(pic_head.BackColor),
                        Wall = ColorD.FromColor(pic_wall.BackColor),
                        Gate = ColorD.FromColor(pic_gate.BackColor),
                        Trap = ColorD.FromColor(pic_trap.BackColor),
                    },
                    FoodManager = new FoodManagerD
                    {
                        MaxFoodNum = Convert.ToInt32(txt_foodnum.Text)
                    },
                    WallManager = new WallManagerD
                    {
                        Walls = Walls
                    },
                    TrapManger = new TrapMangerD
                    {
                        Traps = Traps
                    },
                    SceneSize = new SizeD(Convert.ToInt32(txt_sizex.Text), Convert.ToInt32(txt_sizey.Text)),
                    Snake = snake,
                    GatesD = General.Gates,
                    StartSpeed = Convert.ToInt32(txt_speed.Text)
                };
                var json = js.Serialize(b);
                txtbx_json.Text = json;
                btn_preview.Enabled = true;
                btn_save.Enabled = true;
                btn_upload.Enabled = true;
            }
            catch
            {
                MessageBox.Show("生成失败,请检查参数！");
            }
        }

        private void Pic_bg_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if(dr== DialogResult.OK)
            {
                pic_bg.BackColor = colorDialog1.Color;
            }
        }

        private void pic_head_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_head.BackColor = colorDialog1.Color;
            }
        }

        private void pic_body_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_body.BackColor = colorDialog1.Color;
            }
        }

        private void pic_gate_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_gate.BackColor = colorDialog1.Color;
            }
        }

        private void pic_trap_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_trap.BackColor = colorDialog1.Color;
            }
        }

        private void pic_food_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_food.BackColor = colorDialog1.Color;
            }
        }

        private void pic_wall_Click(object sender, EventArgs e)
        {
            var dr = colorDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                pic_wall.BackColor = colorDialog1.Color;
            }
        }

        private Scene GetSceneFromJson(string json, System.Drawing.Graphics g)
        {
            var barrier = js.Deserialize<Barrier>(json);
            GameComponentFactory.ColorOfBackground = barrier.FactoryOptions.BackGround.GetColor();
            GameComponentFactory.ColorOfFood = new SolidBrush(barrier.FactoryOptions.Food.GetColor());
            GameComponentFactory.ColorOfSnakeBody = new SolidBrush(barrier.FactoryOptions.SnakeBody.GetColor());
            GameComponentFactory.ColorOfSnakeHead = new SolidBrush(barrier.FactoryOptions.SnakeHead.GetColor());
            GameComponentFactory.ColorOfWall = new SolidBrush(barrier.FactoryOptions.Wall.GetColor());
            GameComponentFactory.ColorOfGate = new SolidBrush(barrier.FactoryOptions.Gate.GetColor());
            GameComponentFactory.ColorOfTrap = new SolidBrush(barrier.FactoryOptions.Trap.GetColor());
            var scene = new Scene(barrier.SceneSize.Width, barrier.SceneSize.Height);
            var snake = new Snake.Snake(scene.FreePoints)
            {
                Head = GameComponentFactory.CreateSnakeHead(new Point(barrier.Snake.Head.X, barrier.Snake.Head.Y))
            };
            foreach (var p in barrier.Snake.Bodys)
            {
                snake.Components.Add(GameComponentFactory.CreateSnakeBody(new Point(p.X, p.Y)));
            }
            snake.Direction = Snake.Snake.SnakeDirection.None;
            scene.Snake = snake;
            var foodmgr = new FoodManager(scene.FreePoints)
            {
                MaxFoodNum = barrier.FoodManager.MaxFoodNum
            };
            scene.FoodManager = foodmgr;

            var wallmgr = new WallManager(scene.FreePoints);
            foreach (var p in barrier.WallManager.Walls)
            {
                wallmgr.Components.Add(GameComponentFactory.CreateWall(new Point(p.X, p.Y)));
            }
            scene.WallManager = wallmgr;

            var gatemgr = new GateManager();
            foreach(var p in barrier.GatesD.Gates)
            {
                gatemgr.Gates.Add(GameComponentFactory.CreateGate(new Point(p.Location.X, p.Location.Y), new Point(p.Arrival.X, p.Arrival.Y), p.Direction));
            }
            scene.GateManager = gatemgr;

            var trapmgr = new TrapManager(scene.FreePoints);
            foreach(var p in barrier.TrapManger.Traps)
            {
                trapmgr.Traps.Add(GameComponentFactory.CreateTrap(new Point(p.X, p.Y)));
            }
            scene.TrapManager = trapmgr;

            scene.Score = 0;
            scene.Speed = barrier.StartSpeed;
            scene.Graphics = g;
            return scene;
        }

        private void btn_cls_Click(object sender, EventArgs e)
        {
            Walls = new List<LocationD>();
            Traps = new List<LocationD>();
            b = new Barrier();
            txtbx_json.Text = "";
            btn_save.Enabled = false;
            btn_preview.Enabled = false;
        }

        private void btn_preview_Click(object sender, EventArgs e)
        {
            btn_preview.Enabled = false;
            Form frm_preview = new Form();
            frm_preview.Size = new Size(15 * b.SceneSize.Height + 30, 15 * b.SceneSize.Width + 45);
            Graphics g = frm_preview.CreateGraphics();
            Scene scene = GetSceneFromJson(txtbx_json.Text, g);
            scene.Run();
            frm_preview.ShowDialog();
            scene.Pause();
            frm_preview.Close();
            frm_preview.Dispose();
            scene.EndThread();
        }

        private void Btn_save_Click(object sender, EventArgs e)
        {
            btn_save.Enabled = false;
            var result = saveFileDialog1.ShowDialog();
            if(result== DialogResult.OK)
            {
                File.SaveBarrier(saveFileDialog1.FileName, txtbx_json.Text);
            }
        }

        private void txt_wally_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                Addwall_Clicked(sender, e);
                txt_wallx.Focus();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btn_walleditor_Click(object sender, EventArgs e)
        {
            if (ck_walllr.Checked)
            {
                for (int i = 0; i < Convert.ToInt32(txt_sizex.Text); i++)
                {
                    Walls.Add(new LocationD(0, i));
                    Walls.Add(new LocationD(Convert.ToInt32(txt_sizey.Text) - 1, i));
                }
            }
            if (ck_wallud.Checked)
            {
                for (int i = 0; i < Convert.ToInt32(txt_sizey.Text); i++)
                {
                    Walls.Add(new LocationD(i, 0));
                    Walls.Add(new LocationD(i, Convert.ToInt32(txt_sizex.Text) - 1));
                }
            }
            var frm = new Frm_Editor();
            General.Size = new SizeD(Convert.ToInt32(txt_sizex.Text), Convert.ToInt32(txt_sizey.Text));
            General.SnakeSize = Convert.ToInt32(txt_snakelen.Text);
            General.SnakeHead = new LocationD(Convert.ToInt32(txt_headx.Text), Convert.ToInt32(txt_heady.Text));
            frm.Size = new Size(15 * Convert.ToInt32(txt_sizey.Text) + 300, 15 * Convert.ToInt32(txt_sizex.Text) + 60);
            frm.ShowDialog();
            listBox1.Items.Clear();
            txt_headx.Text = General.SnakeHead.X.ToString();
            txt_heady.Text = General.SnakeHead.Y.ToString();
            foreach(var p in Walls)
            {
                listBox1.Items.Add(p);
            }
            foreach(var p in Traps)
            {
                listBox1.Items.Add(p);
            }
        }

        private void btn_clearall_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();

        }

        private void txt_headx_TextChanged(object sender, EventArgs e)
        {

        }

        private void btn_upload_Click(object sender, EventArgs e)
        {
            new Frm_Upload(txtbx_json.Text, Text ).ShowDialog();
        }

        private void btn_open_Click(object sender, EventArgs e)
        {
            var result = openFileDialog1.ShowDialog();
            if(result== DialogResult.OK)
            {
                string path = openFileDialog1.FileName;
                System.IO.StreamReader reader = new System.IO.StreamReader(path);
                txtbx_json.Text = reader.ReadToEnd();
                Graphics g = CreateGraphics();
                Scene scene = GetSceneFromJson(txtbx_json.Text, g);
                txt_foodnum.Text = scene.FoodManager.MaxFoodNum.ToString();
                txt_sizex.Text = scene.Size.Width.ToString();
                txt_sizey.Text=scene.Size.Height.ToString();
                txt_speed.Text = scene.Speed.ToString();
                txt_headx.Text = scene.Snake.Head.Position.X.ToString();
                txt_heady.Text = scene.Snake.Head.Position.Y.ToString();
                txt_snakelen.Text = scene.Snake.Components.Count.ToString();
                pic_bg.BackColor = GameComponentFactory.ColorOfBackground;
                pic_body.BackColor = ((SolidBrush)GameComponentFactory.ColorOfSnakeBody).Color;
                pic_food.BackColor = ((SolidBrush)GameComponentFactory.ColorOfFood).Color;
                pic_gate.BackColor = ((SolidBrush)GameComponentFactory.ColorOfGate).Color;
                pic_head.BackColor = ((SolidBrush)GameComponentFactory.ColorOfSnakeHead).Color;
                pic_trap.BackColor = ((SolidBrush)GameComponentFactory.ColorOfTrap).Color;
                pic_wall.BackColor = ((SolidBrush)GameComponentFactory.ColorOfWall).Color;

                SnakeD snake = new SnakeD();
                snake.Bodys = new List<LocationD>();
                snake.Head = new LocationD(Convert.ToInt32(txt_headx.Text), Convert.ToInt32(txt_heady.Text));
                for (int i = snake.Head.X - 1; i >= snake.Head.Y - Convert.ToInt32(txt_snakelen.Text); i--)
                {
                    snake.Bodys.Add(new LocationD(i, snake.Head.Y));
                }
                //为预览初始化b
                b = new Barrier
                {
                    FactoryOptions = new FactoryOptions
                    {
                        BackGround = ColorD.FromColor(pic_bg.BackColor),
                        Food = ColorD.FromColor(pic_food.BackColor),
                        SnakeBody = ColorD.FromColor(pic_body.BackColor),
                        SnakeHead = ColorD.FromColor(pic_head.BackColor),
                        Wall = ColorD.FromColor(pic_wall.BackColor),
                        Gate = ColorD.FromColor(pic_gate.BackColor),
                        Trap = ColorD.FromColor(pic_trap.BackColor),
                    },
                    FoodManager = new FoodManagerD
                    {
                        MaxFoodNum = Convert.ToInt32(txt_foodnum.Text)
                    },
                    WallManager = new WallManagerD
                    {
                        Walls = Walls
                    },
                    TrapManger = new TrapMangerD
                    {
                        Traps = Traps
                    },
                    SceneSize = new SizeD(Convert.ToInt32(txt_sizex.Text), Convert.ToInt32(txt_sizey.Text)),
                    Snake = snake,
                    GatesD = General.Gates,
                    StartSpeed = Convert.ToInt32(txt_speed.Text)
                };

                btn_preview.Enabled = true;
                btn_save.Enabled = true;
                btn_upload.Enabled = true;
            }
        }
    }
}
